<template>
  <div class="container">
    <el-form
        ref="loginForm"
        :model="loginForm"
        status-icon
        :rules="rules"
        label-width="80px"
        class="loginContainer"
        v-loading="loading"
        element-loading-text="正在登录..."
        element-loading-spinner="el-icon-loading"
        element-loading-background="rgba(0, 0, 0, 0.8)"
    >
      <h2 class="loginTitle">欢迎登录云E办系统</h2>
      <el-form-item label="用户名" prop="username">
        <el-autocomplete
            style="width: 100%"
            v-model="loginForm.username"
            placeholder="请输入用户名"
            :fetch-suggestions="queryUsername"
            @select="completePassword"
        ></el-autocomplete>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input
            v-model="loginForm.password"
            type="password"
            autocomplete="off"
            placeholder="请输入密码"
        ></el-input>
      </el-form-item>
      <el-form-item label="验证码" prop="code" style="width: 100%">
        <el-input
            v-model="loginForm.code"
            type="text"
            autocomplete="off"
            placeholder="点击图片更换验证码"
            style="width: 70%"
            @keydown.enter="validateLogin('loginForm')"
        ></el-input>
        <!-- 验证码图片框 -->
        <img :src="captchaUrl" alt="验证码" @click="updateCaptcha"
             style="margin: 0 10px;text-align: center"/>
      </el-form-item>
      <el-form-item>
        <div class="remember">
          <el-checkbox v-model="remember">记住密码</el-checkbox>
        </div>

      </el-form-item>
      <el-form-item>
        <el-button @click="validateLogin('loginForm')" type="primary" style="width: 100%">登录</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>

import {postRequest} from "@/utils/api";
import {getRequest} from "@/utils/api";
import Base64 from 'base-64';
import {initMenu} from "@/utils/menus";

export default {
  name: "Login",
  data() {
    const checkName = (rule, value, callback) => {
      if (!value) {
        return callback(new Error('请输入用户名'))
      } else if (value.length < 2 || value.length > 20) {
        return callback(new Error('用户名的长度应在2~20位之间'))
      } else {
        callback()
      }
    };
    const checkPass = (rule, value, callback) => {
      if (!value) {
        return callback(new Error('请输入密码'))
      } else if (value.length < 3) {
        return callback(new Error('密码长度应大于3位'))
      } else {
        callback()
      }
    };
    const checkCode = (rule, value, callback) => {
      if (!value) {
        return callback(new Error('请输入验证码'))
      } else {
        callback()
      }
    }
    return {
      usernameList: [],
      loading: false,
      expire: 7, // 记住密码的过期时间为7天
      captchaUrl: '/captcha?time=' + new Date(),
      remember: true,
      loginForm: {
        username: '',
        password: '',
        code: ''
      },
      rules: {
        username: [{validator: checkName, trigger: ['blur','change']}],
        password: [{validator: checkPass, trigger: 'blur'}],
        code: [{validator: checkCode, trigger: 'blur'}]
      }
    }
  },
  created() {
    for (let i = 0; i < window.localStorage.length; i++) {
      let key = window.localStorage.key(i);
      if (key.startsWith('user_')) {
        let obj = JSON.parse(window.localStorage.getItem(key));
        let expiration = obj.expiration
        if (new Date().getTime() > Date.parse(expiration)) {
          window.localStorage.removeItem(key);
          continue;
        }
        this.usernameList.push(key.substring(5));
      }
    }
  },
  methods: {
    // 自动补全查询用户名列表
    queryUsername(queryString, cb) {
      let usernameList = this.usernameList.map(item => {
            return {value: item}
          }
      );
      const results = queryString ? usernameList.filter(this.createFilter(queryString)) : usernameList;
      cb(results);
    },
    // 用户名列表过滤器
    createFilter(queryString) {
      return (username) => {
        return (username.value.toString().toLowerCase().indexOf(queryString.toLowerCase()) === 0);
      }
    },
    // 选择用户名后自动补全密码
    completePassword() {
      let userObj = JSON.parse(window.localStorage.getItem('user_' + this.loginForm.username));
      if (userObj) {
        this.loginForm.password = Base64.decode(userObj.password);
      }
    },
    // 更新验证码
    updateCaptcha() {
      this.captchaUrl = '/captcha?time=' + new Date();
    },
    // 验证表单并执行登录操作
    validateLogin(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          // 开启loading动画，并执行登录操作
          this.loading = true;
          this.login();
        } else {
          return false;
        }
      })
    },
    // 登录操作
    login() {
      postRequest('/login', this.loginForm).then((res) => {
        if (res && res.obj) {
          // 将token拼接并存入sessionStorage
          const tokenStr = res.obj.tokenHead + ' ' + res.obj.token;
          window.sessionStorage.setItem('tokenStr', tokenStr);
          // 获取用户信息，存入sessionStorage，便于头像等信息展示
          getRequest('/admin/info').then(res=>{
            if (res){
              window.sessionStorage.setItem('user',JSON.stringify(res));
            }
          })
          // 初始化路由
          initMenu(this.$router,this.$store);
          // 如果用户选择记住密码，则将用户名与密码存入localStorage
          if (this.remember) {
            let pass = Base64.encode(this.loginForm.password);
            let loginObj = {
              username: this.loginForm.username,
              password: pass,
              expiration: new Date().getTime() + 1000 * 60 * 60 * 24 * this.expire
            }
            window.localStorage.setItem('user_' + this.loginForm.username, JSON.stringify(loginObj));
          }
          // 关闭loading动画
          this.loading = false;
          // 跳转首页
          setTimeout(() => {
            // 获取带有重定向参数的跳转路径
            let path =  this.$route.query.redirect;
            let pathList = []
            // 判断path是否是有效路由
            this.$router.getRoutes().forEach(item=>{
              pathList.push(item.path)
            })
            if (path!=null && pathList.indexOf(path)!==-1) {
              this.$router.replace(path ==='/'?'/home':path);
            }else {
              this.$router.replace('/home');
            }
          }, 200)
        }
      }).finally(() => {
        this.loading = false
      })
    },
  }
}
</script>

<style>

.loginContainer {
  border-radius: 15px;
  background-clip: padding-box;
  margin: 100px auto;
  width: 50%;
  padding: 15px 35px;
  background: #fff;
  border: 1px solid #eaeaea;
  box-shadow: 0 0 25px #cac6c6;
}

.loginTitle {
  margin: 10px auto 40px auto;
  text-align: center;
}

.el-form-item__content {
  display: flex;
  align-items: center;
}
</style>
